<template>
  <transition name="fade-loading">
    <div class="loading-wrapper" v-show="actualVisible" :class="{ 'local': local }">
      <div class="loading-content">
        <div class="loading-spinner">
          <!-- 视觉元素容器 -->
          <div class="visual-elements">
            <!-- 主星球动画 -->
            <div class="main-planet-container">
              <div class="main-planet"></div>
              <div class="planet-glow"></div>
              <div class="orbit">
                <div class="satellite"></div>
              </div>
            </div>

            <!-- 行星环 -->
            <div class="planet-ring">
              <div class="rings">
                <div class="ring"></div>
                <div class="ring"></div>
                <div class="ring"></div>
              </div>
            </div>

            <!-- 代码片段动画 -->
            <div class="code-snippets">
              <div class="snippet"></div>
              <div class="snippet"></div>
              <div class="snippet"></div>
            </div>

            <!-- 闪烁的星星 -->
            <div class="stars">
              <div class="star" v-for="i in 12" :key="i"></div>
            </div>
          </div>

          <!-- 加载文本容器 -->
          <div class="loading-text-container">
            <transition name="fade-text" mode="out-in">
              <p class="loading-text" :key="currentLoadingText">{{ currentLoadingText }}</p>
            </transition>
            <div class="typing-dots">
              <span class="dot"></span>
              <span class="dot"></span>
              <span class="dot"></span>
            </div>
          </div>
        </div>
      </div>
    </div>
  </transition>
</template>

<script>
import { mapState } from 'vuex'

export default {
  name: 'Loading',
  props: {
    local: {
      type: Boolean,
      default: false
    },
    customTexts: {
      type: Array,
      default: () => []
    },
    loadingType: {
      type: String,
      default: ''
    },
    // 自动检测内容加载完成
    autoDetectReady: {
      type: Boolean,
      default: false
    },
    // 是否可见（由父组件控制）
    visible: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      internalVisible: false,
      minDisplayTime: 600, // 最小显示时间（将根据loadingTarget动态调整）
      showStartTime: 0,
      textIndex: 0,
      textChangeInterval: null,
      defaultLoadingTexts: [
        "🚀 加载中，即将起飞...",
        "🔍 搜索内容中...",
        "💡 读取灵感中...",
        "🌈 构建界面中...",
        "📚 整理知识库中...",
        "⚡ 优化体验中..."
      ],
      loadingFinishedButWaiting: false, // 标记内容已加载但等待最小时间
      loadingTimeoutId: null, // 存储计时器ID
      contentCheckInterval: null, // 检查内容是否准备好的计时器
      forceEndTimeout: null, // 强制结束加载的计时器
      contentDetectionAttempts: 0, // 内容检测尝试次数
      safeLoadingConfig: {
        post: 1200,
        moments: 1000,
        photos: 1500,
        default: 600
      },
      safeLoadingTexts: [],
      safeIsLoading: false,
      safeLoadingTarget: 'default',
      safeContentReady: false,
      safeLoadingStartTime: 0,
      _isNotifyingContentReady: false
    }
  },
  computed: {
    // 安全地访问Vuex状态
    storeState() {
      return this.$store && this.$store.state ? this.$store.state : null;
    },
    // 计算属性而不是直接使用mapState，确保安全访问
    storeLoadingTexts() {
      return this.storeState ? this.storeState.loadingTexts || [] : [];
    },
    storeIsLoading() {
      return this.storeState ? !!this.storeState.isLoading : false;
    },
    storeLoadingTarget() {
      return this.storeState ? this.storeState.loadingTarget || 'default' : 'default';
    },
    storeContentReady() {
      return this.storeState ? !!this.storeState.contentReady : false;
    },
    storeLoadingConfig() {
      return this.storeState && this.storeState.loadingConfig ? this.storeState.loadingConfig : this.safeLoadingConfig;
    },
    storeLoadingStartTime() {
      return this.storeState ? this.storeState.loadingStartTime || 0 : 0;
    },

    // 合并内部状态和props状态
    actualVisible() {
      return this.visible || this.internalVisible;
    },

    effectiveLoadingTexts() {
      // 优先使用路由中的加载文本
      if (this.storeLoadingTexts && this.storeLoadingTexts.length > 0) {
        return this.storeLoadingTexts;
      }
      // 其次使用自定义文本
      if (this.customTexts && this.customTexts.length > 0) {
        return this.customTexts;
      }
      // 最后使用默认文本
      return this.defaultLoadingTexts;
    },
    currentLoadingText() {
      const texts = this.effectiveLoadingTexts;
      return texts && texts.length > 0 ? texts[this.textIndex % texts.length] : "加载中...";
    },
    // 基于loadingTarget获取当前内容类型的最小加载时间
    currentMinDisplayTime() {
      const target = this.loadingType || this.storeLoadingTarget || 'default';
      return this.storeLoadingConfig && this.storeLoadingConfig[target]
        ? this.storeLoadingConfig[target]
        : this.minDisplayTime;
    },
    // 获取当前最大加载时间
    maxLoadingTime() {
      // 最大加载时间是最小显示时间的3倍，但不超过10秒
      return Math.min(this.currentMinDisplayTime * 3, 10000);
    }
  },
  watch: {
    // 监听props的visible属性
    visible(val) {
      if (val) {
        this.showLoading();
      } else {
        this.hideLoading();
      }
    },
    // 监听Vuex的isLoading状态
    storeIsLoading(val) {
      // 当全局加载状态变化时
      if (val) {
        this.showLoading();
        if (this.autoDetectReady) {
          this.startContentReadyDetection();
        }
        // 设置一个安全定时器，确保加载状态不会无限期显示
        this.setupForceEndTimer();
      } else {
        this.hideLoading();
        this.clearAllTimers();
      }
    },
    actualVisible(val) {
      if (!this.local) {
        if (val) {
          document.body.style.overflow = 'hidden';
          document.body.style.touchAction = 'none'; // 防止移动设备上的滚动
          this.showStartTime = Date.now();

          // 如果没有全局加载开始时间，设置一个
          if (!this.storeLoadingStartTime && !this.local && this.$store) {
            this.$store.commit('SET_LOADING_START_TIME', this.showStartTime);
          }

          this.startTextAnimation();
        } else {
          const elapsedTime = Date.now() - (this.storeLoadingStartTime || this.showStartTime);
          const minTime = this.currentMinDisplayTime;

          if (elapsedTime < minTime) {
            // 如果没有显示足够长时间，延迟关闭
            this.loadingFinishedButWaiting = true;
            this.loadingTimeoutId = setTimeout(() => {
              this.releaseBodyScrollLock();
              this.stopTextAnimation();
              this.loadingFinishedButWaiting = false;
            }, minTime - elapsedTime);
          } else {
            this.releaseBodyScrollLock();
            this.stopTextAnimation();
          }
        }
      }
    },
    storeLoadingTexts() {
      // 当加载文本变化时，重置文本索引
      this.textIndex = 0;
    },
    // 当内容准备好且正在等待最小显示时间
    storeContentReady(val) {
      if (val && this.loadingFinishedButWaiting) {
        // 如果内容准备好了，但我们仍在等待最小显示时间
        // 可以考虑缩短等待时间以提升用户体验
        this.shortenWaitingTime();
      }
    }
  },
  methods: {
    releaseBodyScrollLock() {
      document.body.style.overflow = '';
      document.body.style.touchAction = '';
    },
    startTextAnimation() {
      this.textIndex = 0;
      // 定期更换加载文本
      this.textChangeInterval = setInterval(() => {
        this.textIndex = (this.textIndex + 1) % this.effectiveLoadingTexts.length;
      }, 2000); // 降低为2秒，提高用户体验
    },
    stopTextAnimation() {
      if (this.textChangeInterval) {
        clearInterval(this.textChangeInterval);
        this.textChangeInterval = null;
      }
    },
    showLoading() {
      this.internalVisible = true;
    },
    hideLoading() {
      this.internalVisible = false;
    },
    // 检查是否应该显示加载动画
    shouldShowLoading() {
      // 检查是否有开屏动画正在显示
      const splashScreenVisible = document.querySelector('.splash-screen') &&
        !document.querySelector('.splash-screen.fade-out');

      // 只有当没有开屏动画显示时，才触发加载动画
      return !splashScreenVisible;
    },
    // 缩短等待时间
    shortenWaitingTime() {
      if (this.loadingTimeoutId) {
        clearTimeout(this.loadingTimeoutId);
        // 如果内容已经准备好，最多再等待200ms就结束加载动画
        const remainingTime = Math.min(200, this.currentMinDisplayTime - (Date.now() - (this.storeLoadingStartTime || this.showStartTime)));

        if (remainingTime <= 0) {
          this.releaseBodyScrollLock();
          this.stopTextAnimation();
          this.loadingFinishedButWaiting = false;
        } else {
          this.loadingTimeoutId = setTimeout(() => {
            this.releaseBodyScrollLock();
            this.stopTextAnimation();
            this.loadingFinishedButWaiting = false;
          }, remainingTime);
        }
      }
    },
    // 暴露给父组件的方法：通知内容已准备好
    notifyContentReady() {
      // 防止重复执行，避免无限递归
      if (this._isNotifyingContentReady) {
        console.warn('Already notifying content ready, skipping recursive call');
        return;
      }

      this._isNotifyingContentReady = true;

      try {
        // 调试日志
        console.log('Content ready notification received');

        if (!this.local) {
          // 全局加载状态，通过store通知
          if (this.$store && this.$store.dispatch) {
            this.$store.dispatch('contentReady');
          } else {
            console.warn('Store not available in notifyContentReady, using hideLoading directly');
            this.hideLoading();
            // 注意：不再触发content-ready事件，避免潜在的无限循环
          }
        } else {
          // 局部加载状态，直接处理
          this.hideLoading();
        }
      } catch (error) {
        console.error('Error in notifyContentReady:', error);
      } finally {
        // 操作完成后，重置标志位
        this._isNotifyingContentReady = false;
      }
    },

    // 设置强制结束加载的定时器
    setupForceEndTimer() {
      // 清除之前的定时器
      if (this.forceEndTimeout) {
        clearTimeout(this.forceEndTimeout);
      }

      // 设置一个最大显示时间的定时器，防止无限加载
      this.forceEndTimeout = setTimeout(() => {
        console.log('Force ending loading state after timeout');
        if (this.storeIsLoading) {
          this.notifyContentReady(); // 强制通知内容准备好
        }
      }, this.maxLoadingTime);
    },

    // 清除所有计时器
    clearAllTimers() {
      if (this.contentCheckInterval) {
        clearInterval(this.contentCheckInterval);
        this.contentCheckInterval = null;
      }

      if (this.loadingTimeoutId) {
        clearTimeout(this.loadingTimeoutId);
        this.loadingTimeoutId = null;
      }

      if (this.forceEndTimeout) {
        clearTimeout(this.forceEndTimeout);
        this.forceEndTimeout = null;
      }

      if (this.textChangeInterval) {
        clearInterval(this.textChangeInterval);
        this.textChangeInterval = null;
      }
    },

    // 自动检测内容是否准备好
    startContentReadyDetection() {
      // 如果已经在通知内容就绪，不再重复检测
      if (this._isNotifyingContentReady) {
        return;
      }

      this.clearAllTimers();
      this.contentDetectionAttempts = 0;

      // 定期检查DOM是否已加载主要内容
      this.contentCheckInterval = setInterval(() => {
        // 如果已经在通知内容就绪，停止检测
        if (this._isNotifyingContentReady) {
          this.clearAllTimers();
          return;
        }

        this.contentDetectionAttempts++;
        this.checkContentReady();

        // 如果检测超过15次（3秒）还没有结果，增加检测间隔
        if (this.contentDetectionAttempts > 15) {
          clearInterval(this.contentCheckInterval);
          this.contentCheckInterval = setInterval(() => {
            // 再次检查是否已经在通知内容就绪
            if (this._isNotifyingContentReady) {
              this.clearAllTimers();
              return;
            }
            this.checkContentReady();
          }, 500); // 增加到500ms检测一次
        }
      }, 200);

      // 设置最大检测时间，避免无限循环
      setTimeout(() => {
        // 如果已经在通知内容就绪，不再执行
        if (this._isNotifyingContentReady) {
          return;
        }

        if (this.contentCheckInterval) {
          clearInterval(this.contentCheckInterval);
          this.contentCheckInterval = null;
          // 如果超时了还没检测到内容准备好，强制通知准备完成
          console.log('Content detection timeout, forcing content ready');
          // 再次检查是否已经在通知内容就绪
          if (!this._isNotifyingContentReady) {
            this.notifyContentReady();
          }
        }
      }, 8000); // 减少到8秒，避免过长等待
    },

    // 检查内容是否准备好的方法 - 暴露给外部以便直接调用
    checkContentReady() {
      // 如果正在通知内容准备好，避免重复检查
      if (this._isNotifyingContentReady) {
        console.log('Already notifying content ready, skipping content check');
        return false;
      }

      // 检查是否正在加载中
      if (!this.storeIsLoading) {
        console.log('Not in loading state, skipping content check');
        return false;
      }

      // 检查当前路由路径
      const currentRoute = this.$route ? this.$route.path : '';
      if (!currentRoute) {
        console.log('No current route, skipping content check');
        return false;
      }

      console.log('Checking content ready for route:', currentRoute);

      let contentSelectors = [];
      let contentDetected = false;

      // 根据不同的路由设置不同的内容选择器
      if (currentRoute.startsWith('/post/')) {
        contentSelectors = ['.article-content', '.article-container', '.article-body', '.article-detail', '.article-wrapper'];
      } else if (currentRoute === '/moments') {
        contentSelectors = ['.moment-list', '.moments-container', '.moment-item', '.moment-wrapper'];
      } else if (currentRoute.startsWith('/photos')) {
        contentSelectors = ['.photo-gallery', '.photo-detail', '.photo-grid', '.photo-item', '.photos-container'];
      } else {
        contentSelectors = ['.main-content', '.page-content', 'main', '.container', '.content-wrapper', '.el-main'];
      }

      // 检查内容元素是否存在且有内容
      for (const selector of contentSelectors) {
        const contentElements = document.querySelectorAll(selector);
        if (contentElements.length > 0) {
          for (let i = 0; i < contentElements.length; i++) {
            // 检查元素是否有子元素或有文本内容
            if (contentElements[i].childElementCount > 0 ||
              contentElements[i].textContent.trim().length > 0) {
              // 内容已加载
              console.log('Content detected:', selector);
              this.clearAllTimers();
              contentDetected = true;
              break;
            }
          }
          if (contentDetected) break;
        }
      }

      // 如果尚未检测到内容，尝试通过特定类型元素的存在来判断
      if (!contentDetected) {
        // 尝试通过特定类型元素的存在来判断内容是否加载
        const commonContentElements = [
          'article', '.post', '.content',
          '.card', '.list-item', '.data-container',
          '.el-table', '.el-pagination', '.el-card',
          'img[src]:not([src=""])', 'video', 'audio',
          '.el-row', '.home-container', '.about-container'
        ];

        for (const selector of commonContentElements) {
          const elements = document.querySelectorAll(selector);
          if (elements.length > 0) {
            // 找到了一些内容元素
            console.log('Common content elements detected:', selector);
            contentDetected = true;
            break;
          }
        }
      }

      // 如果尚未检测到内容，尝试通过元素数量判断
      if (!contentDetected) {
        // 尝试通过元素数量的突然增加来判断内容是否加载
        const mainEl = document.querySelector('main') || document.querySelector('.main') || document.querySelector('.el-main');

        if (mainEl && mainEl.childElementCount > 3) {
          console.log('Main element has sufficient children:', mainEl.childElementCount);
          contentDetected = true;
        } else {
          // 如果直接是Layout下的主要组件
          const appEl = document.querySelector('#app');
          if (appEl && appEl.childElementCount > 2) {
            const layoutEl = appEl.querySelector('.layout') || appEl.querySelector('.el-container');
            if (layoutEl && layoutEl.childElementCount > 2) {
              console.log('Layout has sufficient content');
              contentDetected = true;
            }
          }
        }
      }

      // 如果检测到内容，通知内容已准备好
      if (contentDetected) {
        this.clearAllTimers();
        this.notifyContentReady();
        return true;
      }

      return false;
    },

    // 直接强制结束加载状态的方法
    forceEndLoading() {
      // 防止重复执行
      if (this._isNotifyingContentReady) {
        console.warn('Already notifying content ready, skipping force end loading');
        return;
      }

      console.log('Force ending loading state');
      this.clearAllTimers();
      this.notifyContentReady();
    }
  },
  mounted() {
    // 如果是本地加载，且传入了加载类型，设置相应的最小显示时间
    if (this.local && this.loadingType) {
      this.minDisplayTime = this.currentMinDisplayTime;
    }

    // 如果已经处于加载状态，启动自动检测和安全定时器
    if (this.storeIsLoading) {
      if (this.autoDetectReady) {
        this.startContentReadyDetection();
      }
      this.setupForceEndTimer();
    }

    // 创建一个专门的事件处理函数，避免直接使用notifyContentReady
    this._handleContentReadyEvent = () => {
      console.log('Global content-ready event received');
      // 避免重复触发
      if (!this._isNotifyingContentReady) {
        this.notifyContentReady();
      }
    };

    // 监听全局事件，允许任何组件通知加载完成
    window.addEventListener('content-ready', this._handleContentReadyEvent);
  },
  beforeDestroy() {
    if (!this.local) {
      this.releaseBodyScrollLock();
    }
    this.clearAllTimers();

    // 移除全局事件监听，使用正确的引用
    if (this._handleContentReadyEvent) {
      window.removeEventListener('content-ready', this._handleContentReadyEvent);
      this._handleContentReadyEvent = null;
    }
  }
}
</script>

<style lang="scss" scoped>
@use "sass:math";

// 全局变量和混合
$primary-color: var(--primary, #409EFF);
$secondary-color: var(--secondary, #67C23A);
$accent-color: var(--accent, #E6A23C);
$bright-accent: var(--bright-accent, #f5a623);
$text-color: var(--text-primary, #303133);
$background-color: var(--card-bg, #ffffff);
$dark-bg: var(--dark-bg, #1f1f1f);
$loading-overlay-light: rgba(255, 255, 255, 0.65);
$loading-overlay-dark: rgba(31, 31, 31, 0.65);

@mixin responsive($breakpoint) {
  @if $breakpoint ==sm {
    @media (max-width: 576px) {
      @content;
    }
  }

  @else if $breakpoint ==md {
    @media (max-width: 768px) {
      @content;
    }
  }

  @else if $breakpoint ==lg {
    @media (max-width: 992px) {
      @content;
    }
  }
}

// 淡入淡出动画
.fade-loading-enter-active,
.fade-loading-leave-active {
  transition: opacity 0.3s ease;
}

.fade-loading-enter,
.fade-loading-leave-to {
  opacity: 0;
}

.fade-text-enter-active,
.fade-text-leave-active {
  transition: opacity 0.3s ease, transform 0.3s ease;
}

.fade-text-enter,
.fade-text-leave-to {
  opacity: 0;
  transform: translateY(10px);
}

// 主容器样式
.loading-wrapper {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9000; // 降低z-index，确保不会覆盖开屏动画
  backdrop-filter: blur(5px);
  background: $loading-overlay-light;
  transition: all 0.3s ease;
  user-select: none; // 防止文本选择

  // 局部加载样式
  &.local {
    position: absolute !important;
    backdrop-filter: blur(3px);
    z-index: 1000;
    width: 100%;
    height: 100%;
    background: rgba(255, 255, 255, 0.7);
  }

  // 深色模式适配
  @media (prefers-color-scheme: dark) {
    background: $loading-overlay-dark;

    &.local {
      background: rgba(30, 30, 30, 0.7);
    }
  }

  // 自定义深色模式类
  .dark-theme & {
    background: $loading-overlay-dark;

    &.local {
      background: rgba(30, 30, 30, 0.7);
    }
  }
}

// 加载内容容器
.loading-content {
  position: relative;
  width: 240px;
  height: 240px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 20px;

  @include responsive(sm) {
    width: 200px;
    height: 200px;
  }
}

// 加载动画容器
.loading-spinner {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 30px;
  animation: spinnerFadeIn 0.5s cubic-bezier(0.22, 1, 0.36, 1);

  .local & {
    transform: scale(0.85);
  }

  @include responsive(sm) {
    gap: 25px;
    transform: scale(0.8);
  }
}

// 视觉元素容器
.visual-elements {
  position: relative;
  width: 140px;
  height: 140px;
  perspective: 1200px;
  transform-style: preserve-3d;
}

// 主行星容器
.main-planet-container {
  position: absolute;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  animation: floatAnimation 4s ease-in-out infinite;

  .main-planet {
    width: 50px;
    height: 50px;
    background: $primary-color;
    border-radius: 50%;
    position: relative;
    box-shadow:
      0 0 15px rgba(64, 158, 255, 0.6),
      0 0 30px rgba(64, 158, 255, 0.2) inset;
    z-index: 2;

    &::after {
      content: '';
      position: absolute;
      width: 18px;
      height: 18px;
      background: rgba(255, 255, 255, 0.8);
      border-radius: 50%;
      top: 12px;
      left: 12px;
      filter: blur(4px);
    }
  }

  .planet-glow {
    position: absolute;
    width: 70px;
    height: 70px;
    background: rgba(64, 158, 255, 0.15);
    border-radius: 50%;
    filter: blur(8px);
    animation: glowPulse 3s ease-in-out infinite;
  }

  .orbit {
    position: absolute;
    width: 120px;
    height: 120px;
    border: 1px dashed rgba(255, 255, 255, 0.3);
    border-radius: 50%;
    animation: orbitRotate 8s linear infinite;

    .satellite {
      position: absolute;
      width: 12px;
      height: 12px;
      background: $bright-accent;
      border-radius: 50%;
      top: 0;
      left: 50%;
      transform: translateX(-50%);
      box-shadow: 0 0 8px rgba(245, 166, 35, 0.6);
    }
  }
}

// 行星环动画
.planet-ring {
  position: absolute;
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
  animation: planetRotate 12s linear infinite;

  .rings {
    position: absolute;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    transform-style: preserve-3d;

    .ring {
      position: absolute;
      width: 100%;
      height: 100%;
      border: 2px solid transparent;
      border-radius: 50%;

      &:nth-child(1) {
        border-top: 2px solid $primary-color;
        animation: ringRotate1 7s linear infinite;
        transform: rotateX(65deg) rotateY(10deg);
      }

      &:nth-child(2) {
        border-right: 2px solid $secondary-color;
        animation: ringRotate2 10s linear infinite;
        transform: rotateX(30deg) rotateY(55deg);
      }

      &:nth-child(3) {
        border-bottom: 2px solid $accent-color;
        animation: ringRotate3 8s linear infinite;
        transform: rotateX(45deg) rotateY(-30deg);
        width: 90%;
        height: 90%;
        top: 5%;
        left: 5%;
      }
    }
  }
}

// 代码片段动画
.code-snippets {
  position: absolute;
  width: 180px;
  height: 180px;
  top: -20px;
  left: -20px;

  .snippet {
    position: absolute;
    height: 3px;
    border-radius: 2px;
    background: $primary-color;
    opacity: 0.7;
    transform-origin: left center;

    &:nth-child(1) {
      width: 35px;
      top: 55px;
      left: 75px;
      animation: snippetPulse 2s ease-in-out infinite;
      animation-delay: 0s;
    }

    &:nth-child(2) {
      width: 50px;
      top: 70px;
      left: 60px;
      animation: snippetPulse 2s ease-in-out infinite;
      animation-delay: 0.6s;
    }

    &:nth-child(3) {
      width: 25px;
      top: 85px;
      left: 85px;
      animation: snippetPulse 2s ease-in-out infinite;
      animation-delay: 1.2s;
    }
  }
}

// 星星动画
.stars {
  position: absolute;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;

  .star {
    position: absolute;
    width: 3px;
    height: 3px;
    background: white;
    border-radius: 50%;
    opacity: 0.7;

    @for $i from 1 through 12 {
      &:nth-child(#{$i}) {
        top: math.random(100) + px;
        left: math.random(100) + px;
        animation: starTwinkle #{1 + math.div(math.random(15), 10)}s ease-in-out infinite;
        animation-delay: #{math.div(math.random(15), 10)}s;
      }
    }
  }
}

// 加载文本容器
.loading-text-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  min-height: 60px; // 确保文本切换时不会改变高度
}

// 加载文本样式
.loading-text {
  color: $text-color;
  font-size: 16px;
  font-weight: 500;
  letter-spacing: 0.5px;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
  margin: 0;
  text-align: center;
  max-width: 200px;

  @media (prefers-color-scheme: dark) {
    color: rgba(255, 255, 255, 0.95);
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
  }

  .dark-theme & {
    color: rgba(255, 255, 255, 0.95);
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
  }

  @include responsive(sm) {
    font-size: 14px;
    max-width: 180px;
  }
}

// 打字动画点
.typing-dots {
  display: flex;
  gap: 5px;

  .dot {
    width: 6px;
    height: 6px;
    background-color: $primary-color;
    border-radius: 50%;
    display: inline-block;

    &:nth-child(1) {
      animation: dotPulse 1.2s infinite;
    }

    &:nth-child(2) {
      animation: dotPulse 1.2s 0.2s infinite;
    }

    &:nth-child(3) {
      animation: dotPulse 1.2s 0.4s infinite;
    }
  }
}

// 动画定义
@keyframes spinnerFadeIn {
  from {
    opacity: 0;
    transform: scale(0.8) translateY(15px);
  }

  to {
    opacity: 1;
    transform: scale(1) translateY(0);
  }
}

@keyframes planetRotate {
  from {
    transform: rotateY(0deg);
  }

  to {
    transform: rotateY(360deg);
  }
}

@keyframes ringRotate1 {
  from {
    transform: rotateX(65deg) rotateY(10deg) rotateZ(0deg);
  }

  to {
    transform: rotateX(65deg) rotateY(10deg) rotateZ(360deg);
  }
}

@keyframes ringRotate2 {
  from {
    transform: rotateX(30deg) rotateY(55deg) rotateZ(0deg);
  }

  to {
    transform: rotateX(30deg) rotateY(55deg) rotateZ(360deg);
  }
}

@keyframes ringRotate3 {
  from {
    transform: rotateX(45deg) rotateY(-30deg) rotateZ(0deg);
  }

  to {
    transform: rotateX(45deg) rotateY(-30deg) rotateZ(360deg);
  }
}

@keyframes snippetPulse {
  0% {
    transform: scaleX(0.3);
    opacity: 0.3;
  }

  50% {
    transform: scaleX(1);
    opacity: 0.8;
  }

  100% {
    transform: scaleX(0.3);
    opacity: 0.3;
  }
}

@keyframes dotPulse {

  0%,
  100% {
    transform: scale(1);
    opacity: 0.5;
  }

  50% {
    transform: scale(1.3);
    opacity: 1;
  }
}

@keyframes floatAnimation {

  0%,
  100% {
    transform: translateY(0);
  }

  50% {
    transform: translateY(-8px);
  }
}

@keyframes glowPulse {

  0%,
  100% {
    opacity: 0.4;
    transform: scale(1);
  }

  50% {
    opacity: 0.8;
    transform: scale(1.2);
  }
}

@keyframes orbitRotate {
  from {
    transform: rotate(0deg);
  }

  to {
    transform: rotate(360deg);
  }
}

@keyframes starTwinkle {

  0%,
  100% {
    opacity: 0.2;
    transform: scale(0.8);
  }

  50% {
    opacity: 1;
    transform: scale(1.3);
  }
}
</style>